home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Text⁄Files / Tape Stuff / scsi.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-02-15  |  5.1 KB  |  259 lines  |  [TEXT/KAHL]

  1. #include <SCSI.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <ctype.h>
  5.  
  6. #include "SCSIDefines.h"
  7. #include "SCSIPrototypes.h"
  8.  
  9. short gSCSIID;
  10.  
  11. short FindTape(char *name, short *id)
  12. {
  13.     unsigned char     string[32];
  14.     short             i;
  15.     
  16.     name[0] = 0;
  17.     for (gSCSIID = 0; gSCSIID < 7; gSCSIID++)
  18.     {
  19.         *id = gSCSIID;
  20.         if (Inquiry(string, sizeof(string)) != OK) continue;
  21.         if (string[0] == 1) 
  22.         {
  23.             memcpy(name, &string[8], 8);
  24.             name[8] = 0;
  25.             for (i = 7; i >= 0; i--)
  26.             {
  27.                  if (isalnum(name[i])) break;
  28.                  name[i] = 0;
  29.             }
  30.             return OK;
  31.         }
  32.     }
  33.     return ERROR;
  34. }
  35.     
  36. short Rewind(void)
  37. {
  38.     while (UnitReady() == ERROR);
  39.     if (Select(gSCSIID) != OK) return ERROR;
  40.     Command(REWIND, 0, 0, 0, 0, 0);
  41.     return Complete(TIMEOUT);
  42. }
  43.  
  44. short WriteBlock(void *ptr)
  45. {
  46.     while (UnitReady() == ERROR);
  47.     if (Select(gSCSIID) != OK) return ERROR;
  48.     Command(WRITE, 1, 0, 0, 1, 0);
  49.     Write(BLOCKSIZE, 1, ptr);
  50.     return Complete(TIMEOUT);
  51. }    
  52.  
  53. short WriteBlocks(void *ptr, unsigned short blocks)
  54. {
  55.     unsigned char *lsb, *msb;
  56.     
  57.     while (UnitReady() == ERROR);
  58.     msb = (unsigned char*)(&blocks);
  59.     lsb = msb + 1;
  60.     if (Select(gSCSIID) != OK) return ERROR;
  61.     Command(WRITE, 1, 0, *msb, *lsb, 0);
  62.     Write(BLOCKSIZE, (long)blocks, ptr);
  63.     return Complete(TIMEOUT);
  64. }    
  65.  
  66. short WriteMark(unsigned short number)
  67. {
  68.     unsigned char *lsb, *msb;
  69.  
  70.     while (UnitReady() == ERROR);
  71.     msb = (unsigned char*)(&number);
  72.     lsb = msb + 1;
  73.     if (Select(gSCSIID) != OK) return ERROR;
  74.     Command(FILE_MARK, 0, 0, *msb, *lsb, 0);
  75.     return Complete(TIMEOUT);
  76. }    
  77.  
  78. short Space(short number, unsigned char type)    /* type = 0 blocks; type = 1 filemarks */
  79. {
  80.     unsigned char *lsb, *msb, *hsb;
  81.     long lnum;
  82.     
  83.     while (UnitReady() == ERROR);
  84.     lnum = number;
  85.     lnum *= 256;
  86.     hsb = (unsigned char*)(&lnum);
  87.     msb = hsb + 1;
  88.     lsb = msb + 1;
  89.     if (Select(gSCSIID) != OK) return ERROR;
  90.     Command(SPACE, type, *hsb, *msb, *lsb, 0);
  91.     return Complete(TIMEOUT);
  92. }    
  93.  
  94. short ReadBlock(void *ptr)
  95. {
  96.     while (UnitReady() == ERROR);
  97.     if (Select(gSCSIID) != OK) return ERROR;
  98.     Command(READ, 1, 0, 0, 1, 0);
  99.     Read(BLOCKSIZE, 1, ptr);
  100.     return Complete(TIMEOUT);
  101. }    
  102.  
  103. short ReadBlocks(void *ptr, unsigned short blocks)
  104. {
  105.     unsigned char *lsb, *msb;
  106.     
  107.     while (UnitReady() == ERROR);
  108.     msb = (unsigned char*)(&blocks);
  109.     lsb = msb + 1;
  110.     if (Select(gSCSIID) != OK) return ERROR;
  111.     Command(READ, 1, 0, *msb, *lsb, 0);
  112.     Read(BLOCKSIZE, (long)blocks, ptr);
  113.     return Complete(TIMEOUT);
  114. }    
  115.  
  116. short Inquiry(void *ptr, unsigned char nBytes)
  117. {
  118.     while (UnitReady() == ERROR);
  119.     if (Select(gSCSIID) != OK) return ERROR;
  120.     Command(INQUIRY, 0, 0, 0, nBytes, 0);
  121.     if (nBytes != 0) Read((long)nBytes, 1, ptr);
  122.     return Complete(TIMEOUT);
  123. }    
  124.  
  125. short UnitReady(void)
  126. {
  127.     if (Select(gSCSIID) != OK) return ERROR;
  128.     Command(UNIT_READY, 0, 0, 0, 0, 0);
  129.     return Complete(TIMEOUT);
  130. }    
  131.  
  132. short Erase(unsigned char restFlag)
  133. {
  134.     while (UnitReady() == ERROR);
  135.     if (restFlag) restFlag = 1;
  136.     if (Select(gSCSIID) != OK) return ERROR;
  137.     Command(ERASE, restFlag, 0, 0, 0, 0);
  138.     return Complete(TIMEOUT);
  139. }    
  140.  
  141. short Select(short lun)
  142. {
  143.     OSErr status;
  144.  
  145.     /* get bus */
  146.     
  147.     status = SCSIGet();
  148.     if (status != noErr) return ERROR;
  149. #ifdef DEBUG
  150.     printf("SCSIGet returns %d\n", status);
  151. #endif    
  152.     /* select device */
  153.     
  154.     status = SCSISelect(lun);
  155.     if (status != noErr) return ERROR;
  156. #ifdef DEBUG
  157.     printf("SCSISelect returns %d\n", status);    
  158. #endif
  159.     return OK;    
  160. }
  161.  
  162. void Command(unsigned char opCode, unsigned char byte1,
  163.      unsigned char byte2, unsigned char byte3, unsigned char byte4, 
  164.      unsigned char controlByte)
  165. {
  166.     SCSI_Command cmd;
  167.     OSErr status;
  168.  
  169.     cmd.opCode = opCode;
  170.     cmd.byte1 = byte1;
  171.     cmd.byte2 = byte2;
  172.     cmd.byte3 = byte3;
  173.     cmd.byte4 = byte4;
  174.     cmd.controlByte = controlByte;
  175.     
  176.     status = SCSICmd((Ptr)&cmd, sizeof(cmd));
  177. #ifdef DEBUG
  178.     printf("SCSICmd returns %d\n", status);
  179. #endif    
  180. }
  181.     
  182. void Read(long blockSize, long numBlocks, void *bufferPtr)
  183. {    
  184.     SCSIInstr tib[3];
  185.     OSErr status;
  186.  
  187.     tib[0].scOpcode = scInc;
  188.     tib[0].scParam1 = (long)bufferPtr;
  189.     tib[0].scParam2 = blockSize;
  190.     tib[1].scOpcode = scLoop;
  191.     tib[1].scParam1 = -10;
  192.     tib[1].scParam2 = numBlocks;
  193.     tib[2].scOpcode = scStop;
  194.     tib[2].scParam1 = 0;
  195.     tib[2].scParam2 = 0;
  196.  
  197.     status = SCSIRead((Ptr)tib);
  198. #ifdef DEBUG
  199.     printf("SCSIRead returns %d\n", status);
  200. #endif    
  201. }
  202.  
  203. void Write(long blockSize, long numBlocks, void *bufferPtr)
  204. {    
  205.     SCSIInstr tib[3];
  206.     OSErr status;
  207.  
  208.     tib[0].scOpcode = scInc;
  209.     tib[0].scParam1 = (long)bufferPtr;
  210.     tib[0].scParam2 = blockSize;
  211.     tib[1].scOpcode = scLoop;
  212.     tib[1].scParam1 = -10;
  213.     tib[1].scParam2 = numBlocks;
  214.     tib[2].scOpcode = scStop;
  215.     tib[2].scParam1 = 0;
  216.     tib[2].scParam2 = 0;
  217.  
  218.     status = SCSIWrite((Ptr)tib);
  219. #ifdef DEBUG
  220.     printf("SCSIWrite returns %d\n", status);
  221. #endif    
  222. }
  223.  
  224. short Complete(long ticks)
  225. {
  226.     OSErr status;
  227.     short stat,message;
  228.     short sense;
  229.  
  230.     status = SCSIComplete(&stat, &message, ticks);
  231. #ifdef DEBUG
  232.     printf("SCSIComplete returns %d stat is %d message is %d\n", status,
  233.         stat, message);
  234. #endif    
  235.         
  236.     if ((stat & 2) != 0) 
  237.     {
  238.         sense = Sense();
  239.         return ERROR;
  240.     }
  241.     return OK;
  242. }
  243.  
  244. short Sense(void)
  245. {
  246.     unsigned char buffer[SENSE_BYTES];
  247.     short i;
  248.  
  249.     Select(gSCSIID);
  250.     Command(REQUEST_SENSE, 0, 0, 0, SENSE_BYTES, 0);
  251.     Read(SENSE_BYTES, 1, buffer);
  252. #ifdef DEBUG
  253.     for (i=0; i<SENSE_BYTES; i+=2) printf("%3d %3d %3d\n",
  254.          i, buffer[i], buffer[i+1]);
  255. #endif
  256.     Complete(TIMEOUT);
  257.     return (short)buffer[0];
  258. }
  259.